Basic Vision stimuli for 7T

Author

Denis Schluppeck

Published

2026-01-19

Stimuli for fMRI experiments written in PsychoPy

Stimuli can either be run via command line (my preferred) if PsychoPy module is installed or via the PsychoPy GUI (to be tested more completely).

Stimulus programs

retinotopy.py - Sliding checkerboard annuli / wedges

Expanding, contracing rings of checkerboard segments that move against each other (step size and direction change probability can be changed)

usage: ./retinotopy.py [-h] [--vpixx] [--no-vpixx] [--coding-window]
                       [--screen-size SCREEN_SIZE SCREEN_SIZE] [--check-timing]
                       [--use-gui] [-obs OBSERVER] [-dir {exp,con,cw,ccw}]
                       [-ct CYCLETIME] [-nc NCYCLES] [-np NULLPERIOD] [-ss STIMSIZE]
                       [-dcw DUTYCYCLEWEDGE] [-dcr DUTYCYCLERING] [-ar ANGULARRATE]
                       [-cp CHANGEPROBABILITY] [-fp FLASHPERIOD] [-e] [-tr TR]

Travelling wedge or annulus stimulus for retinotopic mapping Exp, con, cw, ccw - as per
e.g. matlab implementations of the same.

optional arguments:
  -h, --help            show this help message and exit
  --vpixx               use VPIXX device
  --no-vpixx            run without VPIXX device (eg for testing)
  --coding-window       use small debug window for coding
  --screen-size SCREEN_SIZE SCREEN_SIZE
                        screen size as width height
  --check-timing        check screen timing (false on MacOS: buggy timing!)
  --use-gui             use GUI to set parameters (overrides command line args)
  -obs OBSERVER, --observer OBSERVER
                        Observer code
  -dir {exp,con,cw,ccw}, --direction {exp,con,cw,ccw}
                        exp(anding) or con(tracting) rings, cw or ccw wedge
  -ct CYCLETIME, --cycleTime CYCLETIME
                        How long to complete one cycle (seconds)
  -nc NCYCLES, --nCycles NCYCLES
                        How many blocks?
  -np NULLPERIOD, --nullPeriod NULLPERIOD
                        Duration of gray screen at start (seconds)
  -ss STIMSIZE, --stimSize STIMSIZE
                        Stimulus size (fraction of screen height)
  -dcw DUTYCYCLEWEDGE, --dutyCycleWedge DUTYCYCLEWEDGE
                        Duty cycle for wedge (fraction)
  -dcr DUTYCYCLERING, --dutyCycleRing DUTYCYCLERING
                        Duty cycle for ring (fraction)
  -ar ANGULARRATE, --angularRate ANGULARRATE
                        Angular rate of change
  -cp CHANGEPROBABILITY, --changeProbability CHANGEPROBABILITY
                        Probability of direction change (per frame)
  -fp FLASHPERIOD, --flashPeriod FLASHPERIOD
                        Flash period (seconds)
  -e, --exportStimImage
                        Export stimulus (requires -tr)
  -tr TR, --TR TR       TR / dynamic scan time (required for -e)

./retinotopy.py --onLength 12 --offLength 0 --numBlocks 1 --nullPeriod 0

eccLoc.py - Eccentricity localiser

Alternates two annuli (inner and outer) with a blank period for e.g. 

flowchart LR;
  a[Blank period<br><tt>nullPeriod</tt>] --> b1;
  subgraph Stimulus[Stimulus, <tt>* numBlocks</tt> ]
    b1[Inner annulus<br><tt>onLength</tt>] --> br1[Blank<br><tt>offLength</tt>]; 
    br1 --> b2[Outer annulus<br><tt>onLength</tt>];
    b2 -->  br2[Blank<br><tt>offLength</tt>];
  end;
  br2 --> c1[Good bye];
  style Stimulus fill:#ddd,stroke:#333,stroke-width:2px

usage: ./eccLoc.py [-h] [--vpixx] [--no-vpixx] [--coding-window]
                   [--screen-size SCREEN_SIZE SCREEN_SIZE] [--check-timing] [--use-gui]
                   [-on ONLENGTH] [-off OFFLENGTH] [-nb NUMBLOCKS] [-np NULLPERIOD]
                   [-ss STIMSIZE] [-fp FLASHPERIOD] [-g] [-v]

Visual stimulus that alternates a ring of given eccentricity A with an off block, the
eccentricity B with off block. The eccentricity (full height) corresponds to 1.0
(default), and A and B annuli together cover the full extent of that range

optional arguments:
  -h, --help            show this help message and exit
  --vpixx               use VPIXX device
  --no-vpixx            run without VPIXX device (eg for testing)
  --coding-window       use small debug window for coding
  --screen-size SCREEN_SIZE SCREEN_SIZE
                        screen size as width height
  --check-timing        check screen timing (false on MacOS: buggy timing!)
  --use-gui             use GUI to set parameters (overrides command line args)
  -on ONLENGTH, --onLength ONLENGTH
                        How long is the block on? (seconds)
  -off OFFLENGTH, --offLength OFFLENGTH
                        How long is the block off? (seconds)
  -nb NUMBLOCKS, --numBlocks NUMBLOCKS
                        How many blocks?
  -np NULLPERIOD, --nullPeriod NULLPERIOD
                        Duration of gray screen at start (seconds)
  -ss STIMSIZE, --stimSize STIMSIZE
                        Stimulus size (fraction of screen height)
  -fp FLASHPERIOD, --flashPeriod FLASHPERIOD
                        Flash period (seconds)
  -g                    Use the GUI to set params
  -v                    Set verbose output

./eccLoc.py --onLength 12 --offLength 0 --numBlocks 1 --nullPeriod 0

hemiLoc.py - Left vs Right hemifield localiser

Alternates two annuli (left and right) with a blank period for e.g.

./hemiLoc.py --onLength 12 --offLength 0 --numBlocks 1 --nullPeriod 0
usage: ../hemiLoc.py [-h] [-bl BLOCKLENGTH] [-nb NUMBLOCKS]
                     [-np NULLPERIOD] [-ss STIMSIZE]
                     [-fp FLASHPERIOD] [-g] [-v]

Visual stimulus that alternates a hemifield stimulus between left
and right

optional arguments:
  -h, --help            show this help message and exit
  -bl BLOCKLENGTH, --blockLength BLOCKLENGTH
                        How long is the block on? (seconds)
  -nb NUMBLOCKS, --numBlocks NUMBLOCKS
                        How many blocks?
  -np NULLPERIOD, --nullPeriod NULLPERIOD
                        Duration of gray screen at start (seconds)
  -ss STIMSIZE, --stimSize STIMSIZE
                        Stimulus size (fraction of screen height)
  -fp FLASHPERIOD, --flashPeriod FLASHPERIOD
                        Flash period (seconds)
  -g                    Use the GUI to set params
  -v                    Set verbose output

./hemiLoc.py -bl 12 -nb 10 -np 0 -ss 1.0 -fp 0.25

Use at UoN

These block design and event-related stimuli are designed for use in the 7T scanner at the University of Nottingham. The current iteration emphasises - basic visual stimuli for localising retinotopic areas, LGN, etc. - simple visual task to maintain attention - fexibility to adjust block and event lengths to fit with TR / dynamic scan times of the fMRI experiments

Extensions

  • WIP for documentation… mermaid diagrams, etc. (this document is rendered through quarto so version information will relate to local compile.)

mermaid / version:

  info

Acknowledgements

This repo is a fork of Alex Beckett’s https://github.com/AdvancedMRI/python_stimuli code with some modifications to run on later version of PsychoPy and different handling of command line args. 🙏